"""
用户主界面
@author:yczha
"""
import os
import wx
from threading import Thread
from contextlib import closing

from requests import get as requests_get


from src.config import settings
from src.utils import require_login, user_info, compare_app_version
from src.api.app_version import app_version as api_app_version
from src.ui.transparent_stastictext import TransparentStaticText
from src.ui.pay import OrderDialog
from src.ui.login import LoginDialog
from src.ui.inv_parse import InvParse
from src.ui.words_freq_count import WordsFreqCountUI


class MainUI(wx.Frame):
    """主界面"""

    def __init__(self):
        super(MainUI, self).__init__(None, title=settings.app_title)
        self.panel = wx.Panel(self)
        panel = wx.Panel(self)
        self.back = wx.StaticBitmap(
            panel, bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "bg.png"))
        )
        self.info_tst = None
        self.account_tst = None
        self.login_btn = None
        self.pay_link = None
        self.update_ui_info()

        self.check_version_link = TransparentStaticText(self.back, label="检查更新")
        self.check_version_link.SetPosition((380, 10))
        self.check_version_link.SetFont(
            wx.Font(
                10,
                wx.FONTFAMILY_SWISS,
                wx.FONTSTYLE_ITALIC,
                wx.FONTWEIGHT_LIGHT,
                False,
                "Microsoft YaHei",
            )
        )
        self.check_version_link.SetForegroundColour((0, 0, 255))
        self.check_version_link.Bind(wx.EVT_LEFT_DOWN, self.check_app_version)

        x1, x2, x3 = 50, 180, 310
        y1, y2 = 150, 220
        inv_parse_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "inv-parse.png")),
        )
        inv_parse_btn.SetPosition((x1, y1))
        inv_parse_btn.Bind(wx.EVT_BUTTON, self._go_to_inv_parse)
        inv_det_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "inv-det.png")),
        )
        inv_det_btn.SetPosition((x2, y1))
        inv_det_btn.Bind(wx.EVT_BUTTON, self._go_to_inv_parse)
        inv_det_btn.Disable()
        inv_check_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "inv-check.png")),
        )
        inv_check_btn.SetPosition((x3, y1))
        inv_check_btn.Bind(wx.EVT_BUTTON, self._go_to_inv_parse)
        inv_check_btn.Disable()
        tab_ext_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "tab-ext.png")),
        )
        tab_ext_btn.SetPosition((x2, y2))
        tab_ext_btn.Bind(wx.EVT_BUTTON, self._go_to_inv_parse)
        tab_ext_btn.Disable()
        word_cnt_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "word-cnt.png")),
        )
        word_cnt_btn.SetPosition((x1, y2))
        word_cnt_btn.Bind(wx.EVT_BUTTON, self._go_to_words_cnt)
        # word_cnt_btn.Disable()
        key_val_btn = wx.BitmapButton(
            self.back,
            bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "key-val.png")),
        )
        key_val_btn.SetPosition((x3, y2))
        key_val_btn.Bind(wx.EVT_BUTTON, self._go_to_inv_parse)
        key_val_btn.Disable()

        panel.Fit()
        self.Fit()
        self.Centre()
        self.SetMaxSize(self.GetSize())
        self.SetMinSize(self.GetSize())

    def on_charge_click(self, e):
        with OrderDialog(self) as dlg:
            dlg.ShowModal()
        wx.CallAfter(self.update_ui_info)

    def update_ui_info(self):
        """更新界面信息"""
        if self.account_tst is not None:
            self.account_tst.SetLabel("")
        if self.info_tst is not None:
            self.info_tst.SetLabel("")
        if self.pay_link is not None:
            self.pay_link.SetLabel("")
        if self.login_btn is not None:
            self.login_btn.Hide()
        username, account = user_info()
        if username:
            font = wx.Font(
                12,
                wx.FONTFAMILY_TELETYPE,
                wx.FONTSTYLE_NORMAL,
                wx.FONTWEIGHT_LIGHT,
                False,
                "Microsoft YaHei",
            )
            self.info_tst = TransparentStaticText(self.back, label=username)
            self.info_tst.SetFont(font)
            self.info_tst.SetForegroundColour((255, 255, 255))
            self.info_tst.SetPosition((100, 60))

            self.account_tst = TransparentStaticText(self.back, label=account)
            self.account_tst.SetFont(font)
            self.account_tst.SetForegroundColour((255, 255, 255))
            self.account_tst.SetPosition((100, 82))

            self.pay_link = TransparentStaticText(self.back, label="充值")
            self.pay_link.SetPosition((230, 82))
            self.pay_link.SetFont(
                wx.Font(
                    11,
                    wx.FONTFAMILY_SWISS,
                    wx.FONTSTYLE_ITALIC,
                    wx.FONTWEIGHT_LIGHT,
                    False,
                    "Microsoft YaHei",
                )
            )
            self.pay_link.SetForegroundColour((0, 0, 255))
            self.pay_link.Bind(wx.EVT_LEFT_DOWN, self.on_charge_click)
        else:
            self.login_btn = wx.BitmapButton(
                self.back,
                bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "login.png")),
            )
            self.login_btn.SetPosition((160, 70))
            self.login_btn.Bind(wx.EVT_BUTTON, self.do_login)

    def do_login(self, e):
        with LoginDialog(self) as dlg:
            dlg.ShowModal()
        self.update_ui_info()

    def check_app_version(self, e):
        status, data = api_app_version()
        if status == 1000 and compare_app_version(data["name"]):
            with wx.MessageDialog(
                self,
                f'软件有更新，最新版：{data["name"]}，是否下载？',
                "更新提示",
                wx.YES_NO | wx.ICON_QUESTION,
            ) as dlg:
                if dlg.ShowModal() == wx.ID_YES:
                    with DownloadDialog(self, data) as dlg:
                        dlg.ShowModal()
                        if dlg.STATUS:
                            wx.MessageBox(f"下载完成，请退出本程序启动新版本程序！", "提示", wx.OK | wx.ICON_INFORMATION,)
                            self.Destroy()
                        else:
                            wx.MessageBox(f"下载失败，请重试！", "错误", wx.OK | wx.ICON_ERROR)
        elif status == 1000:
            wx.MessageBox(f"当前已是最新版本：{settings.app_version}", "提示", wx.OK | wx.ICON_INFORMATION)
        else:
            wx.MessageBox(f"获取更新出错，错误信息：{data}", "错误", wx.OK | wx.ICON_ERROR)

    @require_login
    def _go_to_inv_parse(self, e):
        self.update_ui_info()
        with InvParse(self) as dlg:
            dlg.ShowModal()

    def _go_to_words_cnt(self, e):
        with WordsFreqCountUI(self) as dlg:
            dlg.ShowModal()


class DownloadDialog(wx.Dialog):
    """下载软件更新"""

    def __init__(self, parent, app_info):
        super(DownloadDialog, self).__init__(parent, title="下载更新")
        panel = wx.Panel(self)
        self.back = wx.StaticBitmap(
            panel, bitmap=wx.Bitmap(os.path.join(settings.assets_dir, "progress.png"))
        )
        self.app_info = app_info
        self.STOP_TASK = False
        self.STATUS = False
        self.gauge = wx.Gauge(self.back, range=100, size=(320, 20))
        self.gauge.SetPosition((20, 50))
        self.file_lab = TransparentStaticText(self.back, label="0.0%")
        self.file_lab.SetFont(
            wx.Font(
                12,
                wx.FONTFAMILY_MODERN,
                wx.FONTSTYLE_NORMAL,
                wx.FONTWEIGHT_LIGHT,
                False,
                "Microsoft YaHei",
            )
        )
        self.file_lab.SetForegroundColour((0, 0, 255))
        self.file_lab.SetPosition((350, 50))

        panel.Fit()
        self.Fit()
        self.Centre()
        self.SetMaxSize(self.GetSize())
        self.SetMinSize(self.GetSize())

        self.Bind(wx.EVT_CLOSE, self.OnExit)

        self.thread = Thread(target=self.tasks)
        self.thread.setDaemon(True)
        self.thread.start()

    def update_process(self, msg):
        if self.file_lab is not None:
            self.file_lab.SetLabel("")
        self.file_lab = TransparentStaticText(self.back, label=msg)
        self.file_lab.SetFont(
            wx.Font(
                12,
                wx.FONTFAMILY_MODERN,
                wx.FONTSTYLE_NORMAL,
                wx.FONTWEIGHT_LIGHT,
                False,
                "Microsoft YaHei",
            )
        )
        self.file_lab.SetForegroundColour((0, 0, 255))
        self.file_lab.SetPosition((350, 50))

    def OnExit(self, evt):
        self.STOP_TASK = True
        self.DestroyLater()

    def tasks(self):
        try:
            output_path = os.path.join(settings.work_dir, self.app_info["name"])
            with closing(requests_get(self.app_info["url"], stream=True)) as response:
                chunk_size = 102400  # 单次请求最大值
                content_size = int(response.headers["content-length"])  # 内容体总大小
                wx.CallAfter(self.gauge.SetRange, int(content_size // chunk_size))
                with open(output_path, "wb") as fout:
                    for idx, data in enumerate(
                        response.iter_content(chunk_size=chunk_size)
                    ):
                        if self.STOP_TASK:
                            return
                        msg = (
                            f"{round((idx + 1) / content_size * chunk_size * 100, 1)}%"
                        )
                        fout.write(data)
                        wx.CallAfter(self.gauge.SetValue, idx + 1)
                        wx.CallAfter(self.file_lab.SetLabel, msg)
            self.STATUS = True
        except Exception as e:
            wx.MessageBox(f"下载出错：{e}！", "错误提示", wx.OK | wx.ICON_ERROR)
        finally:
            wx.CallAfter(self.Destroy)


def main_wx():
    app = wx.App()
    main_ui = MainUI()
    main_ui.Show()
    app.MainLoop()


if __name__ == "__main__":
    main_wx()
